﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Cms.Domain
{
    [Serializable]
    public class Category : IComparable<Category>
    {
        private IList<Content> _content;
        private DefaultCategorySortKey _defaultSortKey;
        private string _folderName;
        private IList<Folder> _folders;
        private int _id;
        private IList<MediaFile> _mediaFiles;
        private IList<MediaFolder> _mediaFolders;
        private string _name;
        private IList<Page> _pages;
        private Category _parent;
        private Site _site;
        private IList<Category> _subCategories;
        private IList<RssFeed> _rssFeeds;

        public Category()
        {
            _subCategories = new List<Category>();
            _pages = new List<Page>();
            _folders = new List<Folder>();
            _mediaFiles = new List<MediaFile>();
            _mediaFolders = new List<MediaFolder>();
            _content = new List<Content>();
            _rssFeeds = new List<RssFeed>();
        }
        
        public virtual int ID
        {
            get { return _id; }
            set { _id = value; }
        }
        
        public virtual string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public virtual string FolderName
        {
            get { return _folderName; }
            set { _folderName = value; }
        }

        public virtual Site Site
        {
            get { return _site; }
            set { _site = value; }
        }
        
        public virtual Category Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }
        
        public virtual IList<Category> SubCategories
        {
            get { return _subCategories; }
            set { _subCategories = value; }
        }
        
        public virtual DefaultCategorySortKey DefaultSortKey
        {
            get { return _defaultSortKey; }
            set { _defaultSortKey = value; }
        }

        public virtual IList<Page> Pages
        {
            get { return _pages; }
            set { _pages = value; }
        }

        public virtual IList<Folder> Folders
        {
            get { return _folders; }
            set { _folders = value; }
        }

        public virtual IList<MediaFile> MediaFiles
        {
            get { return _mediaFiles; }
            set { _mediaFiles = value; }
        }
        
        public virtual IList<MediaFolder> MediaFolders
        {
            get { return _mediaFolders; }
            set { _mediaFolders = value; }
        }
        
        public virtual IList<Content> Content
        {
            get { return _content; }
            set { _content = value; }
        }

        public virtual IList<RssFeed> RssFeeds
        {
            get { return _rssFeeds; }
            set { _rssFeeds = value; }
        }

        public virtual bool IsParentTo(Category category)
        {
            if (category == null)
                return false;
            Category parent = category.Parent;
            while (parent != null)
            {
                if (parent.ID == ID)
                    return true;
                parent = parent.Parent;
            }
            return false;
        }

        public virtual bool ContainsPage(Page page)
        {
            return page != null && page.IsInCategory(Name);
        }
        
        public virtual bool ContainsFolder(Folder folder)
        {
            return folder != null && folder.IsInCategory(Name);
        }

        public virtual bool ContainsMediaFile(MediaFile file)
        {
            return file != null && file.IsInCategory(Name);
        }
        
        public virtual bool ContainsMediaFolder(MediaFolder folder)
        {
            return folder != null && folder.IsInCategory(Name);
        }

        public virtual bool ContainsContent(Content content)
        {
            return content != null && _content.Any(c => c.ID == content.ID);
        }
        
        public virtual int GetLevelInTree()
        {
            int level = 0;
            Category parent = _parent;
            while (parent != null)
            {
                parent = parent.Parent;
                level++;
            }
            return level;
        }

        public virtual IList<int> GetAllIDs()
        {
            var allIDs = new List<int> { _id };
            foreach (var subcategory in _subCategories)
            {
                allIDs.AddRange(subcategory.GetAllIDs());
            }
            return allIDs;
        }

        public virtual int CompareTo(Category other)
        {
            return this.ID > 0 && this.ID == other.ID ? 0 : 1;
        }
    }
}